package com.ynsj.service.impl;

import com.ynsj.constant.LoginConstant;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class UserServiceDetailServiceImpl implements UserDetailsService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        //区分是后台人员还是我们的用户登录
        String loginType = requestAttributes.getRequest().getParameter("login_type");
        if(StringUtils.isEmpty(loginType)){
            throw new AuthenticationServiceException("登陆类型不能为null！！");
        }
        UserDetails userDetails = null;
        //获取授权类型
        String grantType = requestAttributes.getRequest().getParameter("grant_type");
        if(LoginConstant.REFRESH_TYPE.equals(grantType)){
            //纠正id->username
            username = adjustUsername(username,loginType);
        }
        try {
            switch (loginType) {
                case LoginConstant.ADMIN_TYPE:
                    userDetails = loadSysUserByUsername(username);
                    break;
                case LoginConstant.MEMBER_TYPE:
                    userDetails = loadMemberUserByUsername(username);
                    break;
                default:
                    throw new AuthenticationServiceException("暂不支持的登录方式:" + loginType);
            }
        }catch (IncorrectResultSizeDataAccessException e){ //我们的用户不存在
            throw new UsernameNotFoundException("用户名"+username+"不存在！！");
        }
        return userDetails;
    }


    /**
     * 通过用户id查询用户名称
     * @param username
     * @return
     */
    private String adjustUsername(String username,String loginType) {
        //当用户是管理员时的处理
        if (LoginConstant.ADMIN_TYPE.equals(loginType)){
            return jdbcTemplate.queryForObject(LoginConstant.QUERY_ADMIN_USER_WITH_ID,String.class,username);
        }
        //当用户是普通用户时的处理
        if (LoginConstant.MEMBER_TYPE.equals(loginType)){
            return jdbcTemplate.queryForObject(LoginConstant.QUERY_MEMBER_USER_WITH_ID,String.class,username);
        }
        return username;
    }

    /**
     *
     * 后台人员登录
     * @param username
     * @return
     */
    private UserDetails loadSysUserByUsername(String username) {
        //1.使用用户名查询用户
        return jdbcTemplate.queryForObject(LoginConstant.QUERY_ADMIN_SQL, (resultSet, i) -> {
            if (resultSet.wasNull()){
                throw new UsernameNotFoundException("用户名"+username+"不存在！！");
            }
            long id = resultSet.getLong("id");//用户ID
            String password = resultSet.getString("password");//用户密码
            int status = resultSet.getInt("status");
            return new User(
                    String.valueOf(id),//使用id->username
                    password,
                    status == 1,
                    true,
                    true,
                    true,
                    getSysUserPermissions(id)
            );
        },username);
    }

    //2.查询这个用户的权限

    /**
     * 通过id查询用户的权限
     * @param id
     * @return
     */
    private Collection<? extends GrantedAuthority> getSysUserPermissions(long id) {
        //1.当用户为超级管理员时，他拥有所有的权限数据
        String roleCode = jdbcTemplate.queryForObject(LoginConstant.QUERY_ROLE_CODE_SQL, String.class, id);
        List<String> permissions = null;//权限名称集合
        if(LoginConstant.ADMIN_ROLE_CODE.equals(roleCode)){//超级用户
            permissions = jdbcTemplate.queryForList(LoginConstant.QUERY_ALL_PERMISSIONS, String.class);
        }else{//2.普通用户，需要使用角色查询权限数据
            permissions = jdbcTemplate.queryForList(LoginConstant.QUERY_PERMISSION_SQL,String.class,id);
        }
        if(permissions.isEmpty()){
            return Collections.emptySet();
        }
        return permissions.stream().distinct().map(SimpleGrantedAuthority::new).collect(Collectors.toSet());
    }

    /**
     * 会员的登录
     * @param username
     * @return
     */
    private UserDetails loadMemberUserByUsername(String username) {
        return jdbcTemplate.queryForObject(LoginConstant.QUERY_MEMBER_SQL, (resultSet, i) -> {
            if (resultSet.wasNull()){
                throw new UsernameNotFoundException("用户名"+username+"不存在！！");
            }
            long id = resultSet.getLong("id");//用户ID
            String password = resultSet.getString("password");//用户密码
            int status = resultSet.getInt("status");
            return new User(
                    String.valueOf(id),//使用id->username
                    password,
                    status == 1,
                    true,
                    true,
                    true,
                    Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER"))
            );
        },username,username);
    }

}
